package jl.com.service;

import com.alibaba.fastjson.JSON;
import com.vdurmont.emoji.EmojiParser;
import jl.com.aliyun.check.AliYunOSS;
import jl.com.aliyun.config.ConfigProperties;
import jl.com.entity.Article;
import jl.com.entity.WxNumber;
import jl.com.response.JsonResult;
import jl.com.response.ResultCode;
import jl.com.util.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class ArticeSpiderService {
    private final static Logger log = LoggerFactory.getLogger(ArticeSpiderService.class);

    /**
     * 设置无头模式
     *
     * @return
     */
    public static WebDriver headDriver() {
        ArrayList<String> arg = new ArrayList<>();
        arg.add("enable-automation");
        //初始化一个谷歌浏览器实例，实例名称叫driver
        ChromeOptions chromeOptions = new ChromeOptions()
                //设置 chrome 的无头模式
                .addArguments("--headless")
                .addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
                .addArguments("--disable-gpu")
                .addArguments("--disable-dev-shm-usage")
                .addArguments("--no-sandbox")
                .addArguments("lang=zh_CN.UTF-8")
                //设置Chrome启动时的参数,忽略证书（SSL）错误
                .addArguments("--ignore-certificate-errors")
                //开启一个实验性参数excludeSwitches，用来隐藏window.navigator.webdriver返回true,这个参数必须是List
                .setExperimentalOption("excludeSwitches", arg);
        ;
        WebDriver driver = new ChromeDriver(chromeOptions);
        return driver;
    }

    /**
     * 进入文章详情页获取文章页url
     *
     * @param driver
     * @param wxNumber
     * @return
     * @throws Exception
     */
    public static WebDriver getArticleUrl(WebDriver driver, WxNumber wxNumber) throws Exception {
        String handle1 = driver.getWindowHandle();//获取第一个页面的句柄
        driver.switchTo().window(handle1);
        Thread.sleep(DateUtil.returnDoubleTime(2));

        WebElement webDriver = driver.findElement(By.id("query"));
        if (webDriver != null) webDriver.clear();

        Thread.sleep(DateUtil.returnDoubleTime(2));
        driver.findElement(By.id("query")).sendKeys(wxNumber.getWxNumber());
        Thread.sleep(DateUtil.returnDoubleTime(2));
        //设置加载时长3s
        driver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);
        driver.findElement(By.className("swz2")).click();
        Thread.sleep(DateUtil.returnDoubleTime(2));

        WebElement web = driver.findElement(By.className("news-list2"));
        List<WebElement> lis = web.findElements(By.tagName("li"));
        for (WebElement li : lis) {
            List<WebElement> dls = li.findElements(By.tagName("dl"));
            if (dls.size() > 1) {
                for (WebElement dl : dls) {
                    WebElement webElement = dl.findElement(By.tagName("dd"));
                    try {
                        //如此dd标签没有a标签则continue
                        webElement.findElement(By.tagName("a")).click();
                    } catch (Exception e) {
                        log.error("================异常{},{}", e.getMessage());
                        continue;
                    }
                    break;
                }
                break;
            }
        }
        Thread.sleep(DateUtil.returnDoubleTime(2));
        //定位到新窗口
        String currentWindow = driver.getWindowHandle();
        Set<String> handles = driver.getWindowHandles();
        Iterator<String> it = handles.iterator();
        while (it.hasNext()) {
            String handle = it.next();
            if (currentWindow.equals(handle)) continue;
            driver.switchTo().window(handle);
        }
        return driver;
    }

    /**
     * 根据url抓取文章
     *
     * @param URL
     * @param wxNumber
     * @return
     */
    public static void spiderUrl(String URL, WxNumber wxNumber) throws Exception {
        JdbcDao jdbcDao = new JdbcDao();
        log.info("================根据url抓取文章开始");
        String uuId = "";
        //打开一个站点
        Thread.sleep(DateUtil.returnDoubleTime(2));
        uuId = StringUtil.generateId();
        String taskId = "";
        Article article = new Article();
        //从meta获取当前文章封面
        Document doc = Jsoup.connect(URL)
                //伪装userAgent 为手机游览器，大部分图片大小为自适应，如果用windows 的游览器获取的图片在手机上展示过大超出屏幕
                .userAgent("Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36")
                .get();
        String title = doc.select("#activity-name").text();
        log.info("================title:" + title);
        Article checkFirstTitle = jdbcDao.findContentIdByFirstTitle(title);
        if (checkFirstTitle != null) {
            log.info("================此标题<" + title + ">数据已存在！articleId:" + checkFirstTitle.getId(), "" + checkFirstTitle.getId() + "");
            throw new Exception("文章存在！");
        }
        String style = doc.select("style").get(0).html();
        String covenSrc = doc.select("meta[property=og:image]").get(0).attr("content");
        Document doc2 = doc;
        Elements scripts = doc2.select("script");
        scripts.remove();
        Elements links = doc2.select("link");
        links.remove();
        Elements imgSrcs = doc2.select("img");
        imgSrcs.removeAttr("src");
        Elements elements = doc2.select("iframe");//删除视屏组件，因为在微信无法播放
        elements.remove();

        Element element = doc2.getElementById("meta_content");
        if (element != null) element.remove();//根据id删除dom

        Element element1 = doc2.getElementById("activity-name");
        if (element1 != null) element1.remove();//根据id删除dom

        String html = doc2.getElementById("js_content").html();//body内容
        StringBuffer sb = new StringBuffer();
        sb.append("<div id=\"js_article\" class=\"rich_media \">");
        sb.append("<div class=\"rich_media_inner \">");
        sb.append("<div id=\"page-content\" class=\"rich_media_area_primary \">");
        sb.append("<div  class=\"rich_media_area_primary_inner \">");
        sb.append("<div id=\"img-content\" class=\"rich_media_wrp \">");
        sb.append("<h2 class=\"rich_media_title \" id=\"activity-name\"> " + title + "</h2>");
        sb.append("<div class=\"rich_media_content \" id = \"js_content\"> " + html + "</div>" +
                "</div>" +
                "</div>" +
                "</div>" +
                "</div>" +
                "</div>");
        html = sb.toString();
        Document jsoup = Jsoup.parse(html);
        html = jsoup.body().html();//页面元素排版
        if (!"".equals(covenSrc)) {
            log.info("================下载文章封面");
            /**
             * 下载文章封面
             */
            //将图片转换成base64
            String base64 = "data:image/jpeg;base64," + ImgUtil.imgBase64(covenSrc);
            //将base64编码的图片上传至阿里云并返回图片链接
            String path = AliYunOSS.uploadImage(ConfigProperties.resource.getString("fileName") + System.currentTimeMillis() + ".jpg", base64);
            article.setCover(path);
        }
        article.setArticleId(wxNumber.getId());
        html = HtmUtil.iframeImg(html); //视频背景图片url解码上传替换处理
        List<String> data_srcs = HtmUtil.rtnImgData_Src(html);//截取html元素中的data_src路径
        data_srcs.addAll(HtmUtil.getBackgroundImg(html));//提取背景图片
        data_srcs.add(article.getCover());
        log.info("================将原图片src路径替换成阿里云路径");
        Map<String, Object> map = HtmUtil.updateSrcAliyun(data_srcs, html);//将原图片src路径替换成阿里云路径
        String resultHtml = map.get("html").toString();
//            List<String> srcs =(List<String>)  map.get("srcs");
        article.setTitle(title);
        article.setWxNumber(wxNumber.getWxNumber() + "");
        article.setContent(EmojiParser.parseToAliases(resultHtml));//resultHtml
        article.setStyle(style);
        article.setCreateTime(new Date());
//          EmojiParser.parseToAliases(html)//将表情转换成字符
//          EmojiParser.parseToUnicode(html);      //将字符转换成表情

        log.info(jdbcDao.insertArtice(article) ? "================article添加成功,title:{}" : "================article添加失败,title:{}", article.getTitle(), article.getTitle());
    }

    /**
     * 修改所有已提取文章内容（背景图片）
     *
     * @throws Exception
     */
    @Test
    public void updateArticleContent() throws Exception {
        JdbcDao jdbcDao = new JdbcDao();
        List<Article> articles = jdbcDao.articleList();
        int number = 0;
        for (Article article : articles) {
            number++;
            String html = article.getContent();
            try {
                html = HtmUtil.iframeImg(html); //视频背景图片url解码上传替换处理
                List<String> data_srcs = HtmUtil.rtnImgData_Src(html);//截取html元素中的data_src路径
                data_srcs.addAll(HtmUtil.getBackgroundImg(html));//提取背景图片
                data_srcs.add(article.getCover());
                Map<String, Object> map = HtmUtil.updateSrcAliyun(data_srcs, html);//将原图片src路径替换成阿里云路径
                String resultHtml = map.get("html").toString();
                article.setContent(resultHtml);
                log.info("================第{}文章内容修改{}", number, jdbcDao.updateArticle(article));
            } catch (Exception e) {
                log.error("================error：{}", e.getMessage());
            }
        }
    }

    /**
     * 删除文章内容中的视屏组件
     * @throws Exception
     */
    @Test
    public void deleteContentIframe() throws Exception {
        JdbcDao jdbcDao = new JdbcDao();
        List<Article> articles = jdbcDao.articleList();
        int number = 0;
        for (Article article : articles) {
            number++;
            String html = article.getContent();
            try {
                Document jsoup = Jsoup.parse(html);
                Elements elements = jsoup.select("iframe");
                elements.remove();
                article.setContent(jsoup.body().html());
                log.info("================第{}文章内容修改{}", number, jdbcDao.updateArticle(article));
            } catch (Exception e) {
                log.error("================error：{}", e.getMessage());
            }
        }
    }

    /**
     * 根据文章链接提取文章
     * 测试图片data-src问题
     * @throws Exception
     */
    @Test
    public void updateData_src() throws Exception {
        Document doc = Jsoup.connect("https://mp.weixin.qq.com/s?src=11&timestamp=1594548146&ver=2456&signature=46PE9eI*idjGp*nSXRidlmIotMEzWjiAznByaobr3KuQUVZfduZbfztt8vXJYEyM4d7fOhyoaF70Qvh*nvAXe60WJZOkVMYepTzXc4KIrc5uuP7ZhtqirDK7qccPQVyF&new=1")
                .userAgent("Mozilla/5.0 (Linux; Android 6.0.1; OPPO R9s Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045130 Mobile Safari/537.36 MMWEBID/6420 MicroMessenger/7.0.12.1620(0x27000C36) Process/tools NetType/4G Language/zh_CN ABI/arm64")
                .get();
        String title = doc.select("#activity-name").text();
        log.info("================title:" + title);
        String style = doc.select("style").get(0).html();
        String covenSrc = doc.select("meta[property=og:image]").get(0).attr("content");
        Document doc2 = doc;
        Elements scripts = doc2.select("script");
        scripts.remove();
        Elements links = doc2.select("link");
        links.remove();
        Elements imgSrcs = doc2.select("img");
        imgSrcs.removeAttr("src");
        Elements elements = doc2.select("iframe");
        elements.remove();

        Element element = doc2.getElementById("meta_content");
        if (element != null) element.remove();//根据id删除dom

        Element element1 = doc2.getElementById("activity-name");
        if (element1 != null) element1.remove();//根据id删除dom

        String html = doc2.getElementById("js_content").html();//body内容
        StringBuffer sb = new StringBuffer();
        sb.append("<div id=\"js_article\" class=\"rich_media \">");
        sb.append("<div class=\"rich_media_inner \">");
        sb.append("<div id=\"page-content\" class=\"rich_media_area_primary \">");
        sb.append("<div  class=\"rich_media_area_primary_inner \">");
        sb.append("<div id=\"img-content\" class=\"rich_media_wrp \">");
        sb.append("<h2 class=\"rich_media_title \" id=\"activity-name\"> " + title + "</h2>");
        sb.append("<div class=\"rich_media_content \" id = \"js_content\"> " + html + "</div>" +
                "</div>" +
                "</div>" +
                "</div>" +
                "</div>" +
                "</div>");
        html = sb.toString();
        String path = "";
        if (!"".equals(covenSrc)) {
            log.info("================下载文章封面");
            /**
             * 下载文章封面
             */
            //将图片转换成base64
            String base64 = "data:image/jpeg;base64," + ImgUtil.imgBase64(covenSrc);
            //将base64编码的图片上传至阿里云并返回图片链接
             path = AliYunOSS.uploadImage(ConfigProperties.resource.getString("fileName") + System.currentTimeMillis() + ".jpg", base64);
        }
        html = HtmUtil.iframeImg(html); //视频背景图片url解码上传替换处理
        List<String> data_srcs = HtmUtil.rtnImgData_Src(html);//截取html元素中的data_src路径
        data_srcs.addAll(HtmUtil.getBackgroundImg(html));//提取背景图片
        data_srcs.add(path);
        log.info("================将原图片src路径替换成阿里云路径");
        Map<String, Object> map = HtmUtil.updateSrcAliyun(data_srcs, html);//将原图片src路径替换成阿里云路径
        String resultHtml = map.get("html").toString();
        System.out.println(resultHtml);
    }
}
